package com.assignwork.dto;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import org.springblade.core.tool.utils.Func;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Data
public class StatisticsThroughputForecastCargoDTO {

    private static final String[] CN_MONTH = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"};
    private static final List<String> CARGO_ZH = Arrays.asList("gc", "hf", "ls", "qt");
    private static final Map<String, String> NAME_CODE_MAP = new HashMap<String, String>() {{
        put("其他", "qt");
        put("化肥", "hf");
        put("有色矿", "ysk");
        put("粮食", "ls");
        put("钢材", "gc");
        put("铁矿", "tk");
    }};

    private String endTime;
    private String titleName;
    @JsonSerialize(using = ToStringSerializer.class)
    private Long titleId;
    private BigDecimal planTon;

    private String getTitleCode() {
        if (Func.isNotBlank(getTitleName())) {
            String tn = getTitleName();
            if (NAME_CODE_MAP.containsKey(tn)) {
                return NAME_CODE_MAP.get(tn);
            }
        }
        return "error";
    }

    private String getPlanTonStr() {
        if (planTon != null) {
            return planTon.toString();
        }
        return "";
    }

    private boolean isZh() {
        return CARGO_ZH.contains(getTitleCode());
    }

    private static String toZh(String name) {
        if (Func.isNotBlank(name)) {
            return CN_MONTH[Func.toInt(name) - 1] + "月";
        }
        return name;
    }

    public static List<Map<String, String>> getData(List<StatisticsThroughputForecastCargoDTO> ls) {
        List<Map<String, String>> res = new ArrayList<>();
        Map<String, Map<String, String>> tmp = new HashMap<>();
        Map<String, List<StatisticsThroughputForecastCargoDTO>> dateMap = ls.stream().collect(Collectors.groupingBy(StatisticsThroughputForecastCargoDTO::getEndTime));
        BigDecimal tTon = BigDecimal.ZERO;
        BigDecimal zTon = BigDecimal.ZERO;
        for (Map.Entry<String, List<StatisticsThroughputForecastCargoDTO>> date : dateMap.entrySet()) {
            String key = date.getKey();
            List<StatisticsThroughputForecastCargoDTO> value = date.getValue();
            Map<String, String> cargoGroupMap = value.stream().collect(Collectors.toMap(StatisticsThroughputForecastCargoDTO::getTitleCode, StatisticsThroughputForecastCargoDTO::getPlanTonStr));
            BigDecimal zhTon = value.stream().filter(StatisticsThroughputForecastCargoDTO::isZh).map(StatisticsThroughputForecastCargoDTO::getPlanTon).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal totalTon = value.stream().map(StatisticsThroughputForecastCargoDTO::getPlanTon).reduce(BigDecimal.ZERO, BigDecimal::add);

            tTon = tTon.add(totalTon);
            zTon = zTon.add(zhTon);

            cargoGroupMap.put("zhTon", zhTon.toString());
            cargoGroupMap.put("totalTon", totalTon.toString());
            cargoGroupMap.put("endTimeStr", toZh(key));
            cargoGroupMap.put("endTime", Func.toInt(key, 0) + "");

            tmp.put(toZh(key), cargoGroupMap);
        }
        Map totalMap = ls.stream().collect(
                Collectors.groupingBy(
                        StatisticsThroughputForecastCargoDTO::getTitleCode,
                        Collectors.mapping(
                                StatisticsThroughputForecastCargoDTO::getPlanTon,
                                Collectors.reducing(BigDecimal.ZERO, BigDecimal::add)
                        )
                ));

        totalMap.put("endTime", "99");
        totalMap.put("zhTon", zTon);
        totalMap.put("totalTon", tTon);
        totalMap.put("endTimeStr", "合计");

        int i = 1;
        for (String s : CN_MONTH) {
            if (tmp.containsKey(s + "月")) {
                res.add(tmp.get(s + "月"));
            } else {
                Map<String, String> map = new HashMap<>();
                map.put("endTimeStr", s + "月");
                map.put("endTime", i + "");
                res.add(map);
            }
            i++;
        }

        res.sort((a, b) -> {
            return Func.toInt(a.get("endTime"), 0) - Func.toInt(b.get("endTime"), 0);
        });

        res.add(totalMap);

        return res;
    }

}
